package frsf.cidisi.exercise.arqueologo.search.actions;

import frsf.cidisi.exercise.arqueologo.search.*;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;
import frsf.cidisi.faia.state.AgentState;
import frsf.cidisi.faia.state.EnvironmentState;

public class RecogerCofre extends SearchAction {

    /**
     * This method updates a tree node state when the search process is running.
     * It does not updates the real world state.
     */
    @Override
    public SearchBasedAgentState execute(SearchBasedAgentState s) {
        ArqueologoAgentState agState = (ArqueologoAgentState) s;
        // if (agState.getPercepcionCofre() == ArqueologoPerception.COFRE_LLENO ) {
        if (agState.getmundo().getCofre(agState.getPosicion()) != null) {

            // Update the agent state -> sacar cofre de la aldea, cargarlo en el acoplado, disminuir capacidad
            if (agState.getmundo().getCofre(agState.getPosicion()).getPeso() <= agState.getCapacidadRestante()) {
                agState.agregarCofre(agState.getmundo().getCofre(agState.getPosicion()));
                agState.setCapacidadRestante(agState.getCapacidadRestante() - agState.getmundo().getCofre(agState.getPosicion()).getPeso());
                //agState.setPercepcionCofre(ArqueologoPerception.COFRE_VACIO);
                agState.getmundo().getAldea(agState.getPosicion()).llevarCofre();
                return agState;
            }
        }
        return null;
    }

    /**
     * This method updates the agent state and the real world state.
     */
    @Override
    public EnvironmentState execute(AgentState ast, EnvironmentState est) {
        ArqueologoEnvironmentState environmentState = (ArqueologoEnvironmentState) est;
        ArqueologoAgentState agState = ((ArqueologoAgentState) ast);
//      if (agState.getmundo().getAldea(agState.getPosicion()).getPercepcion() == ArqueologoPerception.COFRE_LLENO ) {

        /**
         * Funcion que simula la accion del Pirata en robar el tesoro. Nosotros
         * suponemos que el pirata es muy codicioso y roba el tesoro completo...
         */
        double pirataGaston = Math.random();

        if (pirataGaston < 0.4) {
            agState.resultado.setUbicacionPirata(agState.getPosicion());
            agState.getmundo().restarTesoro(agState.getPosicion());
            agState.getmundo().getAldea(agState.getPosicion()).llevarCofre();
            environmentState.getmundo().getAldea(agState.getPosicion()).llevarCofre();
        }

        if (agState.getmundo().getCofre(agState.getPosicion()) != null) {
            if (agState.getmundo().getCofre(agState.getPosicion()).getPeso() <= agState.getCapacidadRestante()) {
                System.out.println("Decidio recoger en " + agState.getPosicion());
                agState.agregarCofre(agState.getmundo().getCofre(agState.getPosicion()));
                agState.setCapacidadRestante(agState.getCapacidadRestante() - agState.getmundo().getCofre(agState.getPosicion()).getPeso());
                agState.getmundo().restarTesoro(agState.getPosicion());
                environmentState.getmundo().getAldea(agState.getPosicion()).llevarCofre();
                agState.getmundo().getAldea(agState.getPosicion()).llevarCofre();
                return environmentState;
            }
        } else {
            System.out.println("Oh, ah pasado el pirata Gaston!!");
            agState.setPosicion(agState.ultimaAldeaVisitada());
            environmentState.setposicionArqueologo(agState.ultimaAldeaVisitada());
            agState.quitarUltimaAldeaVisitada();
            return environmentState;
        }
        return null;
    }

    /**
     * This method returns the action cost.
     */
    @Override
    public Double getCost() {
        return new Double(0);
    }

    /**
     * This method is not important for a search based agent, but is essensial
     * when creating a calculus based one.
     */
    @Override
    public String toString() {
        return "Recoger";
    }
}
